package server;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**This class have a thread that Wakes up once a day and responsible for two things: 
 * 1.send email notification to readers that need to return book in the next day
 * 2.check if some reader who made an order didnt came to take the book after two days,if so his order is deleted.
 */
public class BackroundPerforming extends Thread {
	/**connection to db,this class get this connection from DBhandler.java class*/
	Connection conn;
	public BackroundPerforming(Connection conn){
		this.conn=conn;
	}
	
	/**function that sleep for 24 hours and checks for unfulfilled orders and books that need to be returen the next day*/
	public void run()
	{
		String str;
		java.sql.ResultSet rs2,rs1,rs=null;
		Date today = new Date();
		int bookcatalog;
		String email,bookname;
		long   now;
		long other = 0;
		Statement stmt = null,stmt2,stmt3;
		String message;
		String MAIL_SERVER = "smtp.gmail.com";
    	String USERNAME = "madgirit@gmail.com";
    	String PASSWORD = "tGAcc09V";
		String fromAddress = "madgirit@gmail.com";
		String subject = "Message from library";

		while(true){
			this.checkTwoDayNotifiedOrders();
		   str="SELECT * FROM BorrowHistory WHERE actualReturnDate IS NULL";
			try {
				stmt = conn.createStatement();
				rs =  stmt.executeQuery(str);
			} catch (Exception e) {
				e.printStackTrace();
			}
	    now=today.getTime();
		try {
			while(rs.next()){
				other=rs.getDate(5).getTime();
				if(Math.abs(other-now)<=86400000){
					//when entering this if than it means that one day left for borrowing
					bookcatalog=rs.getInt(2);
					
					//get the reader email
					str="SELECT email FROM Reader WHERE ReaderId='"+rs.getInt(3)+"'";
					stmt2=conn.createStatement();
					rs1=stmt2.executeQuery(str);
					rs1.next();
					email=rs1.getString(1);
					
					//get the bookname
					str="SELECT bookName FROM Book WHERE CatalogNumber='"+rs.getInt(2)+"'";
					stmt3=conn.createStatement();
					rs2=stmt3.executeQuery(str);
					rs2.next();
					bookname=rs2.getString(1);
					
					//send an email to reader
					 message="Dear Reader, You have one day to return the book: "+bookname+" CatalogNumber: "+bookcatalog;
			    	try {
			    		Properties properties = System.getProperties();
			    		properties.put("mail.smtps.host", MAIL_SERVER);
			    		properties.put("mail.smtps.auth", "true");

			    		Session session = Session.getInstance(properties);
			    		MimeMessage msg = new MimeMessage(session);

			    		msg.setFrom(new InternetAddress(fromAddress));
			    		msg.addRecipients(javax.mail.Message.RecipientType.TO, email);
			    		msg.setSubject(subject);
			    		msg.setText(message);

			    		Transport tr = session.getTransport("smtps");
			    		tr.connect(MAIL_SERVER, USERNAME, PASSWORD);
			    		tr.sendMessage(msg, msg.getAllRecipients());
			    		tr.close();
			    		} catch (AddressException ex) {
			    		System.out.println(ex.getMessage());
			    		} catch (MessagingException ex) {
			    		System.out.println(ex.getMessage());
			    		}
			    	System.out.println("a reminder email was sent to "+email);
			    	// end of sending mail
					rs2.close();
					rs1.close();
				}
				
				

			}//end of  internal while
			
			try {                //sleep for 24 hours
				sleep(86400000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
			
		
		}//end of  external while
		
		
	}

/**checks for unfulfilled orders
 * returns nothing
 * */
	private void checkTwoDayNotifiedOrders()
	{
		String str="SELECT * FROM Orders WHERE notified=1";
		Statement stmt = null;
		java.sql.ResultSet rs;
		Date today = new Date();
		Date d;
		long mili,militoday;
		PreparedStatement ps;
		
		try {
			stmt=conn.createStatement();
			rs =  stmt.executeQuery(str);
			while(rs.next()){
				d=rs.getDate(7);
				mili=d.getTime();
				militoday=today.getTime();
				if((militoday-mili)>=172800000){
					ps = conn.prepareStatement("Delete from Orders Where OrderId=? ");
					ps.setInt(1, rs.getInt(1));			
					ps.executeUpdate();	
					System.out.println("An order id:"+rs.getInt(1)+" was deleted");	
				}	
			}
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
	}
	

}
